/*****************************************
  NAME: RTC.c
  DESC: RTC test
  WWW.YCTEK.COM
 *****************************************/
#include "2410addr.h"
#include "2410lib.h"
#include "RTC.h"

char *day[8] = {" ","Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"};
volatile int isRtcInt, isInit = 2;
volatile unsigned int sec_tick;

void * func_rtc_test[][2]=
{	
		(void *)Test_Rtc_Alarm, 			"RTC Alarm      ",
		(void *)Display_Rtc,						"RTC Display    ", 	 
		(void *)Test_Rtc_Tick,				"RTC Tick       ",
	0,0
};

void Rtc_Test(void)
{
	int i;
	
	Uart_Printf("\n======  RTC Test program start ======\n");
		
	while(1)
	{
		i=0;
		Uart_Printf("\n\n");
		while(1)
		{
			Uart_Printf("%2d:%s",i,func_rtc_test[i][1]);
			i++;
			if((int)(func_rtc_test[i][0])==0)
			{
				Uart_Printf("\n");
				break;
			}
			if((i%4)==0)
			Uart_Printf("\n");
		}

		Uart_Printf("\nPress Enter key to exit : ");
		i = Uart_GetIntNum();
		if(i==-1) break;
		if(i>=0 && (i<((sizeof(func_rtc_test)-1)/8)) )
			( (void (*)(void)) (func_rtc_test[i][0]) )();
	}
	
	Uart_Printf("\n====== RTC Test program end ======\n");
}

void Display_Rtc(void)
{
    int year,tmp,key;                   
    int month,date,weekday,hour,min,sec;

    rRTCCON = 0x01;
    Uart_Printf("Press any key to exit.\n\n");
    while(!Uart_GetKey())
    {    
        while(1)
        {
				if(rBCDYEAR == 0x99) 
						year = 0x1999;
				else 
						year		= 0x2000 + rBCDYEAR;
				month 	= rBCDMON;
				weekday = rBCDDAY;
				date		= rBCDDATE;
				hour		= rBCDHOUR;
				min 		= rBCDMIN;
				sec 		= rBCDSEC;
				
				if(sec!=tmp)
				{
						tmp = sec;
						break;
				}
		} 		 
		Uart_Printf("%2x : %2x : %2x	%10s,  %2x/%2x/%4x\n",hour,min,sec,day[weekday],month,date,year);
    }
    rRTCCON = 0x0;
}



void Test_Rtc_Alarm(void)  
{
    Uart_Printf("[ RTC Alarm Test for S3C2440 ]\n");

    Rtc_Init();

    rRTCCON  = 0x01;
    rALMYEAR = TESTYEAR2 ;
    rALMMON  = TESTMONTH2;
    rALMDATE = TESTDATE2  ;
    rALMHOUR = TESTHOUR2 ;
    rALMMIN  = TESTMIN2  ;
    rALMSEC  = TESTSEC2 + 2; 
	Uart_Printf("After 2 sec, alarm interrupt will occur.. \n");
	
    isRtcInt = 0;
    pISR_RTC = (unsigned int)Rtc_Int;
    rRTCALM  = 0x7f;
    rRTCCON  = 0x0;
    rINTMSK  = ~(BIT_RTC);

    while(isRtcInt==0);
    
    rINTMSK = BIT_ALLMSK;

}


void Rtc_Init(void)
{
    rRTCCON  = rRTCCON  & ~(0xf)  | 0x1;
    
    rBCDYEAR = rBCDYEAR & ~(0xff) | TESTYEAR;
    rBCDMON  = rBCDMON  & ~(0x1f) | TESTMONTH;
    rBCDDATE = rBCDDATE & ~(0x3f) | TESTDATE;         
    rBCDDAY  = rBCDDAY  & ~(0x7)  | TESTDAY;
    rBCDHOUR = rBCDHOUR & ~(0x3f) | TESTHOUR;
    rBCDMIN  = rBCDMIN  & ~(0x7f) | TESTMIN;
    rBCDSEC  = rBCDSEC  & ~(0x7f) | TESTSEC;
    
    rRTCCON  = 0x0;
}


void Rtc_TimeSet(void)
{
    int syear,smonth,sdate,shour,smin,ssec;
    int sday;

    Uart_Printf("[ RTC Time Setting ]\n");
    Rtc_Init();
    Uart_Printf("RTC Time Initialized ...\n");
    
    Uart_Printf("Year (Two digit the latest)[0~99] : ");
    syear = Uart_GetIntNum();
    
    Uart_Printf("Month                      [1~12] : ");
    smonth = Uart_GetIntNum();
    
    Uart_Printf("Date                       [1~31] : ");
    sdate = Uart_GetIntNum();
          
    Uart_Printf("\n1:Sunday  2:Monday  3:Thesday  4:Wednesday  5:Thursday  6:Friday  7:Saturday\n");
    Uart_Printf("Day of the week                   : ");
    sday = Uart_GetIntNum();
    
    Uart_Printf("Hour                       [0~23] : ");
    shour = Uart_GetIntNum();
    
    Uart_Printf("Minute                     [0~59] : ");
    smin = Uart_GetIntNum();
    
    Uart_Printf("Second                     [0~59] : ");
    ssec = Uart_GetIntNum();
    
    rRTCCON  = rRTCCON  & ~(0xf)  | 0x1;
    
    rBCDYEAR = ((syear/10)<<4)+(syear%10);
    rBCDMON  = ((smonth/10)<<4)+(smonth%10);
    rBCDDAY  = sday;
    rBCDDATE = ((sdate/10)<<4)+(sdate%10);
    rBCDHOUR = ((shour/10)<<4)+(shour%10);
    rBCDMIN  = ((smin/10)<<4)+(smin%10);
    rBCDSEC  = ((ssec/10)<<4)+(ssec%10);
    
	Uart_Printf("%2d : %2d : %2d	%10s,  %2d/%2d/%4d\n",shour,smin,ssec,day[sday],smonth,sdate,syear);
	Uart_Printf("%2x : %2x : %2x	%10s,  %2x/%2x/%4x\n"
		,rBCDHOUR,rBCDMIN,rBCDSEC,day[rBCDDAY],rBCDMON,rBCDDATE,rBCDYEAR);
    rRTCCON  = 0x0;   
}


void Test_Rtc_Tick(void)
{
    Uart_Printf("[ RTC Tick interrupt(1 sec) test for S3C2440 ]\n");
    Uart_Printf("Press any key to exit.\n"); 
    Uart_Printf("\n");  
    Uart_Printf("\n");      
    Uart_Printf("   ");    
        
    pISR_TICK = (unsigned)Rtc_Tick;
    sec_tick  = 1;
    rINTMSK   = ~(BIT_TICK); 
    rRTCCON   = 0x0;
    rTICNT    = (1<<7) + 127;

    Uart_Getch();
    
    rINTMSK   = BIT_ALLMSK;
    rRTCCON   = 0x0;
}


void __irq EINT0_int(void)
{
    rSRCPND = BIT_EINT0;   
    rINTPND = BIT_EINT0;
    rINTPND;

    rRTCRST = (1<<3) | 3;
}


void __irq Rtc_Int(void)
{
    rSRCPND = BIT_RTC;   
    rINTPND = BIT_RTC;
    rINTPND;

    Uart_Printf("RTC Alarm Interrupt O.K.\n");
    isRtcInt = 1;  
}


void __irq Rtc_Tick(void)
{
    rSRCPND = BIT_TICK;   
    rINTPND = BIT_TICK;
    rINTPND;

    Uart_Printf("\b\b\b\b\b\b\b%03d sec",sec_tick++);
}
